package com.facebook.app.client.presenter;

import java.util.List;

import com.facebook.app.client.ClusteringMethod;
import com.facebook.app.client.FacebookServiceAsync;
import com.facebook.app.client.event.ActionFailedEvent;
import com.facebook.app.client.event.ClusteringEndedEvent;
import com.facebook.app.shared.clustering.Clusterable;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;

public class ReadyForClusteringPresenter implements Presenter {
	
	public interface Display {
		Image getLoadingImage();
		Widget asWidget();
	}
	
	private final FacebookServiceAsync rpcService;
	private final HandlerManager eventBus;
	private final Display view;
	private final ClusteringMethod selectedClusteringMethod;
	
	private final List<Clusterable> clusterElements;
	
	public ReadyForClusteringPresenter(FacebookServiceAsync rpcService, HandlerManager eventBus, Display view, ClusteringMethod selectedClusteringMethod, List<Clusterable> clusterElements) {
		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.view = view;
		this.selectedClusteringMethod = selectedClusteringMethod;
		this.clusterElements = clusterElements;
	}
	
	@Override
	public void go(final HasWidgets container) {
		container.clear();
		container.add(view.asWidget());
		
		initiateClustering();
	}
	
	private void initiateClustering() {
		
		if (clusterElements != null && clusterElements.size() == 0) {
			eventBus.fireEvent(new ActionFailedEvent("No friends to cluster!"));
			return;
		}
		
		rpcService.initiateClustering(selectedClusteringMethod, clusterElements, new AsyncCallback<List<Clusterable>>() {
			@Override
			public void onSuccess(List<Clusterable> clusteringResults) {
				
				switch (selectedClusteringMethod.getClusteringType()) {
				
				case HIERARCHICAL_CLUSTERING:
					if (clusteringResults.size() == 1) {
						eventBus.fireEvent(new ClusteringEndedEvent(clusteringResults));
					} else {
						rpcService.initiateClustering(selectedClusteringMethod, clusteringResults, this);
					}
					break;
					
				default:
					eventBus.fireEvent(new ClusteringEndedEvent(clusteringResults));
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				eventBus.fireEvent(new ActionFailedEvent("Clustering failed!"));
			}
		});
	}
	
}
